package fserv.entities;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PushbackInputStream;
import java.net.InetAddress;

/**
 * Abstract class representing a message of the Chat System communication protocol.
 * 
 * @author Arthur Bit-Monnot <abit@etud.insa-toulouse.fr>
 * @author Julien Marchand <jmarchan@etud.insa-toulouse.fr>
 */
public abstract class Message {
    /**
     * Address of the sender of the message.
     */
    private InetAddress sourceAddr;

    /**
     * Gets the sender of the message.
     * 
     * @return the InetAddress of the sender of the message.
     */
    public InetAddress getSourceAddr() {
        return this.sourceAddr;
    }

	private int sourcePort;

	public void setSourcePort(int sourcePort) {
		this.sourcePort = sourcePort;
	}

	public int getSourcePort() {
		return sourcePort;
	}
    
    /**
     * Sets the sender of the message.
     * 
     * @param addr the InetAddress of the sender of the message.
     */
    public void setSourceAddr(InetAddress addr) {
        this.sourceAddr = addr;
    }
    
    /**
     * Writes a Message to an output stream (e.g. to a socket or a byte array).
     * Must be implemented by all subclasses of Message.
     * 
     * @param stream the output stream
     */
    public abstract void writeToStream(OutputStream stream) throws IOException;
    
    /**
     * Creates a Message from a input stream (e.g. from a socket or a byte array).
     * 
     * @param stream the input stream
     * @return the corresponding message
     * @throws MalformedMsgException if the message is malformed
     */
    public static Message fromStream(InputStream stream) throws InvalidMsgIdException, IOException {
        PushbackInputStream pis = new PushbackInputStream(stream);
        byte msgId = (byte) pis.read();
        pis.unread(msgId);
        switch (msgId) {
            case 1:
                return new Reply(pis);
            case 10:
                return new Command(pis);
            case 15:
                return new FileProposition(pis);
            default:
                throw new InvalidMsgIdException(msgId);
        }
    }
}